﻿using System.Threading;
using JetBlack.Diagnostics;

namespace JetBlack.Services
{
    /// <summary>
    /// Creates an instance of a managed server which will be launched in a background worker thread.
    /// </summary>
    /// <typeparam name="ManageableServer">An instance of a class which implements <see cref="IManageableServer">IManageableServer</see>.</typeparam>
    public class ManagedServer<ManageableServer> where ManageableServer : IManageableServer
    {
        private Thread serverThread = null;

        /// <summary>
        /// The contained server.
        /// </summary>
        public ManageableServer Server { get; private set; }

        /// <summary>
        /// The default constructor.
        /// </summary>
        public ManagedServer()
            : this(default(ManageableServer))
        {
        }

        /// <summary>
        /// Construct from a <paramref name="server"/>.
        /// </summary>
        /// <param name="server">The server to contain.</param>
        public ManagedServer(ManageableServer server)
        {
            Server = server;
        }

        /// <summary>
        /// Start the server.
        /// </summary>
        public void Start(string[] args)
        {
            if (serverThread != null)
            {
                Server.TraceSource.Warning("The server is already running");
            }
            else
            {
                serverThread = new Thread(x => Server.Start((string[])x))
                {
                    Name = "ManagerThread",
                    IsBackground = true
                };

                serverThread.Start(args);
            }
        }

        /// <summary>
        /// Stop the server.
        /// </summary>
        public void Stop()
        {
            if (serverThread == null)
            {
                Server.TraceSource.Warning("The server is not running");
            }
            else
            {
                Server.Stop();
                serverThread.Join();
                serverThread = null;
            }
        }

        /// <summary>
        /// Pause the server.
        /// </summary>
        public void Pause()
        {
            if (serverThread != null)
                Server.Pause();
        }

        /// <summary>
        /// Resume from a paused state.
        /// </summary>
        public void Resume()
        {
            if (serverThread != null)
                Server.Resume();
        }
    }
}
